package com.tinysand.advert.handler;

import com.alibaba.fastjson.JSON;
import com.tinysand.advert.index.DataTable;
import com.tinysand.advert.index.IndexAware;
import com.tinysand.advert.index.impl.*;
import com.tinysand.advert.index.support.AdPlanObject;
import com.tinysand.advert.index.support.AdUnitObject;
import com.tinysand.advert.index.support.AdUnitRelObject;
import com.tinysand.advert.index.support.AdvertObject;
import com.tinysand.advert.mysql.constant.OperationType;
import com.tinysand.advert.support.*;
import com.tinysand.advert.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * 索引之间存在层级划分，即依赖关系划分
 *
 * Created By TINY
 * Create Time 2020/2/27
 **/
@Slf4j
public class AdLevelDataHandler {

    private static <K, V> void handleBinlogEvent(
            IndexAware<K, V> indexAware,
            K key, V value, OperationType operationType) {

        switch (operationType) {
            case ADD:
                indexAware.add(key, value); break;

            case UPDATE:
                indexAware.update(key, value); break;

            case DELETE:
                indexAware.delete(key, value); break;
            default: break;
        }
    }

    public static void handleLevel2(AdPlanTable planTable,
                                    OperationType operationType) {
        AdPlanObject planObject = new AdPlanObject(
                planTable.getId(),
                planTable.getUserId(),
                planTable.getPlanStatus(),
                planTable.getStartDate(),
                planTable.getEndDate()
        );
        handleBinlogEvent(DataTable.of(AdPlanIndex.class),
                planObject.getPlanId(), planObject, operationType);
    }

    public static void handleLevel2(AdvertTable advertTable,
                                    OperationType operationType) {
        AdvertObject advertObject = new AdvertObject(
                advertTable.getAdId(),
                advertTable.getName(),
                advertTable.getType(),
                advertTable.getMaterialType(),
                advertTable.getHeight(),
                advertTable.getWidth(),
                advertTable.getAuditStatus(),
                advertTable.getAdUrl()
        );
        handleBinlogEvent(DataTable.of(AdvertIndex.class),
                advertObject.getAdId(), advertObject, operationType);
    }

    public static void handleLevel3(AdUnitTable unitTable,
                                    OperationType operationType) {
        AdPlanObject adPlanObject = DataTable.of(
                AdPlanIndex.class
        ).get(unitTable.getPlanId());

        if (null == adPlanObject) {
            log.error("错误，推广单元对应的推广计划还未创建，推广计划id： ({})",
                    unitTable.getPlanId());
            return;
        }

        AdUnitObject adUnitObject = new AdUnitObject(
                unitTable.getUnitId(),
                unitTable.getUnitStatus(),
                unitTable.getPositionType(),
                unitTable.getPlanId(),
                adPlanObject
        );
        handleBinlogEvent(DataTable.of(AdUnitIndex.class),
                unitTable.getUnitId(), adUnitObject, operationType);
    }

    public static void handleLevel3(AdUnitRelTable adUnitRelTable,
                                    OperationType operationType) {

        if (operationType == OperationType.UPDATE) {
            log.error("广告与推广单元的关系索引不支持更新操作");
            return;
        }

        AdUnitObject unitObject = DataTable.of(
                AdUnitIndex.class
        ).get(adUnitRelTable.getUnitId());

        AdvertObject advertObject = DataTable.of(
                AdvertIndex.class
        ).get(adUnitRelTable.getAdId());

        if (null == unitObject || null == advertObject) {
            log.error("广告与推广单元的关系索引创建失败，参数：（{}）",
                    JSON.toJSONString(adUnitRelTable));
            return;
        }

        AdUnitRelObject adUnitRelObject = new AdUnitRelObject(
                adUnitRelTable.getUnitId(),
                adUnitRelTable.getAdId()
        );

        handleBinlogEvent(DataTable.of(AdUnitRelIndex.class),
                CommonUtils.stringConcat(
                        adUnitRelTable.getAdId().toString(),
                        adUnitRelTable.getUnitId().toString()
                ), adUnitRelObject, operationType);
    }

    public static void handleLevel4(
            DistrictTable districtTable, OperationType operationType) {
        if (operationType == OperationType.UPDATE) {
            log.error("地域索引不支持更新操作");
            return;
        }

        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class)
                .get(districtTable.getUnitId());
        if (null == adUnitObject) {
            log.error("地域索引创建失败，参数：（{}）",
                    JSON.toJSONString(districtTable));
            return;
        }

        String key = CommonUtils.stringConcat(
                districtTable.getProvince(),
                districtTable.getCity()
        );

        Set<Long> value = new HashSet<>(Collections.singleton(
                districtTable.getUnitId()));

        handleBinlogEvent(DataTable.of(DistrictIndex.class),
                key, value, operationType);
    }

    public static void handleLevel4(
            InterestTable interestTable, OperationType operationType) {
        if (operationType == OperationType.UPDATE) {
            log.error("兴趣索引不支持更新操作");
            return;
        }

        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class)
                .get(interestTable.getUnitId());
        if (null == adUnitObject) {
            log.error("兴趣索引创建失败，参数：（{}）",
                    JSON.toJSONString(interestTable));
            return;
        }

        Set<Long> value = new HashSet<>(Collections.singleton(
                interestTable.getUnitId()));

        handleBinlogEvent(DataTable.of(InterestIndex.class),
                interestTable.getItTag(), value, operationType);
    }

    public static void handleLevel4(
            KeywordTable keywordTable, OperationType operationType) {
        if (operationType == OperationType.UPDATE) {
            log.error("关键字索引不支持更新操作");
            return;
        }

        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class)
                .get(keywordTable.getUnitId());
        if (null == adUnitObject) {
            log.error("关键字索引创建失败，参数：（{}）",
                    JSON.toJSONString(keywordTable));
            return;
        }

        Set<Long> value = new HashSet<>(Collections.singleton(
                keywordTable.getUnitId()));

        handleBinlogEvent(DataTable.of(InterestIndex.class),
                keywordTable.getKeyword(), value, operationType);
    }
}
